//*****************************************************************************
//  172x72 COG Display Temp. Comp. FW
//  MCU: MSP430F235
//  PCB: 10424
//  Compiler: TI Code Composer Essentials MSP430 v3.1
//  Kent Displays, Inc.
//  Copyright (c) 2009. All rights reserved worldwide.
//  Revisions
//     A - Initial. (24V Drive System, No Focal Conic Erase)
//     B - 28V Drive System, Focal Conic Erase
//*****************************************************************************

#include "system.h"
#include "mystring.h" 
#include "hal_ucs.h"

#define UART_DEBUG
#define RTC_DEBUG
//#define RF_DEBUG
//#define LCD_DEBUG
#define LED_DEBUG
//#define GT_DEBUG

#ifdef GT_DEBUG
#include "GT22.h"
#endif

#ifdef LED_DEBUG
#include "led.h" 
#endif

#ifdef LED_DEBUG
#define LED1_RESET() LED1_reset()
#define LED2_RESET() LED2_reset()
#define LED1_TOGGLE() LED1_toggle()
#define LED2_TOGGLE() LED2_toggle()
#define LED1_SET() LED1_set()
#define LED2_SET() LED2_set()
#else
#define LED1_RESET()
#define LED2_RESET() 
#define LED1_TOGGLE()
#define LED2_TOGGLE() 
#define LED1_SET() 
#define LED2_SET()
#endif

#ifdef RF_DEBUG
#include "CC2500.h"
#endif

#ifdef RTC_DEBUG
#include "rtc.h"
#endif

#ifdef UART_DEBUG
#include "uart.h"
#define PRINT_CHAR(x) print_char(x) 
#define PRINT(x) print(x)
#define PRINT_RF(x, length) print_rf(x, length)
#else
#define PRINT_CHAR(x)
#define PRINT(x)
#define PRINT_RF(x, length)
#endif

volatile Calendar newTime;

typedef enum {  LPM4_MODE, LPM3_MODE, ACTIVE_MODE, APPLICATION_MODE } McuStatus;
volatile McuStatus CpuMode = ACTIVE_MODE;

typedef enum {  TURE = 0, FALSE = !TURE } FlagStatus;

volatile FlagStatus timeFlag = TURE;

volatile FlagStatus uart_receive_flag = TURE;

unsigned char rxBuffer[64];

void main(void)
{   
	// System Initialization
	StopWatchdog();               // Stop watchdog timer.
	ConfigPorts();                // Configure I/O ports.
//	ConfigClocks();               // Configure basic clock module.
    
    P5SEL |= BIT4 + BIT5;                       // Port select XT1
 
	//Initialize clock and peripherals
	LFXT_Start(XT1DRIVE_3, XCAP_3);
    Init_FLL_Settle(8000, 244);
    SFRIE1 |= OFIE;

#ifdef GT_DEBUG    
    GT_config();
#endif

#ifdef LED_DEBUG    
    LED_config();
#endif
    
#ifdef UART_DEBUG
     UART_config();
     PRINT("hello world!");
#endif

#ifdef RF_DEBUG
    SPI_SELECT();
    SPI_SET_CLK();
    SPI_DIS_SELECT();
    cc2500_Init(0x00);
    Set_CCxx00Rxd();
#endif

#ifdef RTC_DEBUG
	setupRTC();
#endif

#ifdef RF_DEBUG

    P2IES |= 0x01;
    P2IFG &= ~0x01;
    P2IE  |= 0x01;
#endif

    _BIS_SR(GIE);
	
	CpuMode = ACTIVE_MODE;

	while (1) {
        switch (CpuMode)
        {
        case ACTIVE_MODE:
			
            if ((timeFlag == FALSE)) {
                timeFlag = TURE;
    			newTime = rtc_getCalendarTime();
                LED1_TOGGLE();
                PRINT_CHAR(hextodec(newTime.Hours) / 10 + 48);
                PRINT_CHAR(hextodec(newTime.Hours) % 10 + 48);
                PRINT_CHAR(':');
                PRINT_CHAR(hextodec(newTime.Minutes) / 10 + 48);
                PRINT_CHAR(hextodec(newTime.Minutes) % 10 + 48);
                PRINT_CHAR(':');
                PRINT_CHAR(hextodec(newTime.Seconds) / 10 + 48);
                PRINT_CHAR(hextodec(newTime.Seconds) % 10 + 48);    
                
                PRINT_CHAR('\n');
		    }

			break;
		case LPM3_MODE:
          
				PRINT("go lowPowerMode3!");
                
                do
                {
                    PRINT("go while");
                    __bis_SR_register(LPM3_bits + GIE); // Enter LPM3
                    __no_operation();
                    
                }  while (CpuMode != ACTIVE_MODE);
                
                PRINT("go out while");
                
                SFRIE1 &= ~OFIE;                        //disable oscillator fault before configuring FLL
                Init_FLL_Settle(8000, 244);   												
                SFRIE1 |= OFIE;
  
                PRINT("go wakeup");
            break;
        }
	}
}

#ifdef RTC_DEBUG

#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR (void)
{
    switch (__even_in_range(RTCIV,16)){
        case 0: break;  //No interrupts
        case 2:         //RTCRDYIFG
            //Toggle P1.0 every second
            timeFlag = FALSE; 
            LED1_TOGGLE();
            
            break;
        case 4:         //RTCEVIFG

            break;
        case 6:         //RTCAIFG
            //Interrupts 5:00pm on 5th day of week
            
            if (CpuMode == ACTIVE_MODE) {
                CpuMode = LPM3_MODE;
                PRINT("go LPM3_MODE interrupt");
            } else if (CpuMode == LPM3_MODE) {
                CpuMode = ACTIVE_MODE;
				__bic_SR_register_on_exit(LPM3_bits);
            }
			
            __no_operation();
            break;
        case 8: break;  //RT0PSIFG
        case 10: break; //RT1PSIFG
        case 12: break; //Reserved
        case 14: break; //Reserved
        case 16: break; //Reserved
        default: break;
    }
}

#endif

#ifdef UART_DEBUG

unsigned char k = 0x00;
unsigned char c = 0x00;

#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{
    switch (__even_in_range(UCA1IV,4)){
        //Vector 2 - RXIFG
        case 2:

            //USCI_A0 TX buffer ready?
            while (!UART_getInterruptStatus(UCTXIFG));
            c = UART_receiveData();
            print_char(c);
			TxBuffer[k] = c;
	
			if ((TxBuffer[k - 2] == 0x0D) && (TxBuffer[k - 1] == 0x0D) && (TxBuffer[k] == 0x0D)) {
                if ((uart_receive_flag == TURE)) {
    			    uart_receive_flag = FALSE;
					str_cpy(rxBuffer, TxBuffer, k - 2);
					str_set(TxBuffer, 64, 0x00);
					k = 0;
			    }
			} else {
                if (k++ > 64) {
                    k = 0;
                }				
			}
			
            break;
        default: break;
    }
}

#endif

#pragma vector=UNMI_VECTOR
__interrupt void UNMI_ISR(void)
{
    switch (SYSUNIV)
    {
        case 0x0004:  LFXT_Start(XT1DRIVE_3, XCAP_3); break;
        default: break;
    }
}
